package uk.ac.lkl.lpp.model.xml;



import java.util.Map;
import java.util.logging.Logger;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import uk.ac.lkl.common.util.ds.AbstractNotifyingList;
import uk.ac.lkl.common.util.ds.NotifyingList;
import uk.ac.lkl.common.util.ds.NotifyingMap;
import uk.ac.lkl.lpp.model.PedagogyPlanModel;

import uk.ac.lkl.lpp.model.ldo.TeachingMethod;


public class TeachingMethodHoursAllocationSetProcessor extends
        ModelElementProcessor {

    private static final Logger logger = Logger.getLogger("uk.ac.lkl.lpp");


    public TeachingMethodHoursAllocationSetProcessor() {
        super("TeachingMethodHoursAllocationSet");
    }


    public void convertDataToElements(PedagogyPlanModel plan,
                                      Document document,
                                      Element pedagogyPlanElement) {

        Element hoursElement = document
                .createElement("TeachingMethodHoursAllocationSet");
        pedagogyPlanElement.appendChild(hoursElement);

        // hack to use this to look up indices all the time
        AbstractNotifyingList<TeachingMethod> teachingMethods = plan
                .getList("main", TeachingMethod.class);

        Map<TeachingMethod, Float> map = plan
                .getMap(
                        "TeachingMethodHoursAllocation",
                        TeachingMethod.class,
                        Float.class);
        for (Map.Entry<TeachingMethod, Float> entry : map.entrySet()) {
            TeachingMethod teachingMethod = entry.getKey();
            Float hours = entry.getValue();

            // user didn't specify it
            if (hours == null)
                continue;

            int index = teachingMethods.indexOf(teachingMethod);

            Element entryElement = document
                    .createElement("TeachingMethodHoursAllocation");
            entryElement.setAttribute("teachingMethodIndex", Integer
                    .toString(index));
            entryElement.setAttribute("hours", Float.toString(hours));

            hoursElement.appendChild(entryElement);
        }
    }


    public void convertElementToData(PedagogyPlanModel plan, Element element) {
        NotifyingMap<TeachingMethod, Float> map = new NotifyingMap<TeachingMethod, Float>();

        AbstractNotifyingList<TeachingMethod> teachingMethods = plan
                .getList("main", TeachingMethod.class);

        NodeList nodes = element
                .getElementsByTagName("TeachingMethodHoursAllocation");
        for (int i = 0; i < nodes.getLength(); i++) {
            try {

                Element childElement = (Element) nodes.item(i);
                logger.info("ChildElement :" + childElement);

                String indexString = childElement
                        .getAttribute("teachingMethodIndex");

                int index = Integer.parseInt(indexString);

                TeachingMethod teachingMethod = teachingMethods.get(index);

                String hoursString = childElement.getAttribute("hours");
                float hours = Float.parseFloat(hoursString);

                map.put(teachingMethod, hours);
            }
            catch (NumberFormatException e) {
                // todo: add to warning list
                e.printStackTrace();
            }
            catch (IndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        }
        plan.addMap(
                    "TeachingMethodHoursAllocation",
                    TeachingMethod.class,
                    Float.class,
                    map);
    }

}
